/*
 * Copyright 2011 Philippe Blanc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package me.l1k3.fx.client.channel;

import me.l1k3.core.client.Core;
import me.l1k3.fx.client.channel.impl.StyleChannelImplJS;
import me.l1k3.fx.client.channel.inter.Channel;
import me.l1k3.fx.client.channel.inter.ChannelContext;
import me.l1k3.fx.client.channel.trait.TraitDecorator;
import me.l1k3.fx.client.engine.inter.FXEngine;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;

public abstract class StyleChannel implements Channel {
	protected String name;
	protected boolean backward;
	protected boolean accumulate;
	protected TraitDecorator trait;

	public StyleChannel() {
	    trait = new TraitDecorator();
	}
	
	//- - - factory
	
    public final static StyleChannel create(String type) {
        if (type.equals(FXEngine.JS)) {
            return new StyleChannelImplJS();
        }
        
        return GWT.create(StyleChannel.class);
    }
	
	public final static StyleChannel setStyle(String type, String property, int start, int end, Unit unit) {
        StyleChannel channel = create(type);
        channel.setName(property);
        channel.setRange(start, end);
        channel.setInteger(true);
        channel.setUnit(unit);

        return channel;
    }
	
	public final static StyleChannel setStyle(String type, String property, double start, double end, Unit unit) {
		StyleChannel channel = create(type);
		channel.setName(property);
		channel.setRange(start, end);
		channel.setUnit(unit);

		return channel;
	}
	
	//- - -
    
	public final void setName(String name) {
		this.name = name;
	}

	public final void setUnit(Unit unit) {
		if(unit==null)
		trait.setUnit("");
		else
	    trait.setUnit(unit.getType());
	}
	
	public final void setInteger(boolean integer) {
	    trait.setInteger(integer);
	}
	
	public final void setRange(int start, int end) { 
        trait.set(start, end);
    }
	
	public final void setRange(double start, double end) { 
	    trait.set(start, end);
	}
	
	public final void setAccumulate(boolean accumulate) {
        this.accumulate = accumulate;
    }
    
    protected final void setStyle(ChannelContext context, boolean backward) {       
        context.getStyle().setProperty(name, trait.getString(backward));
    }
	
	//- - -
	
    @Override
    public boolean isForward() {
        return !backward;
    }
    
    @Override
    public void init(ChannelContext context) { 
        if(name.equals("left") || name.equals("top")) {
            Style style = context.getStyle();
            String position = Core.getComputedStyleProperty(context.getElement(), "position"); //style.getPosition();
            
            if(position.length()==0 || position.equals("static"))
            style.setProperty("position", "relative");
        }
        
        if(name.equals("width") || name.equals("height")) {
            Style style = context.getStyle();
            String display = Core.getComputedStyleProperty(context.getElement(), "display");  //String display = style.getDisplay();
            
            if(display.length()==0 || display.equals("inline")) {
                style.setProperty("display", "block");
            }
            
            style.setProperty("overflow", "hidden");
        }
        
        setStyle(context, backward);
    }
    
    @Override
    public void toggle(ChannelContext context) {
        if(!accumulate) {
            backward = !backward;
            setStyle(context, backward);
        }
    }
    
    /*
    @Override
    public void start(ChannelContext context) { }
    */
    
    /*
    @Override
    public void update(ChannelContext context) { }
    */
    
	@Override
	public void complete(ChannelContext context) {
		if(accumulate) {
		    trait.accumulate();
		}
	
		toggle(context);
	}
}
